<?php
/**
 * PddSpec.php class file.
 * @author wudg <544038230@qq.com>
 * @date 2020/12/18- 下午4:01
 */

namespace common\jobs\copy\tools;

use common\exception\CopyException;
use common\helpers\AmountHelper;
use common\helpers\CopyHelper;
use common\helpers\ImagesHelper;
use common\helpers\StringHelper;
use common\jobs\models\PddFilterTpl;
use Imagine\Exception\RuntimeException;
use Yii;
use yii\base\Exception;
use yii\helpers\ArrayHelper;
use yii\imagine\Image;

class PddSpec
{

    /**
     * 自动填写字段映射关系
     * @var array
     */
    public static $autoInput = [
        '生产日期' => 'production_data',
        '保质期' => 'shelf_life',
        '包装方式' => 'packing_way',
        '食品生产许可证编号' => 'food_license_no',
        '是否为特殊用途化妆品' => 'special_cosmetics',
        '化妆品批准文号' => 'cosmetics_batch_no',
        '玩具类型' => 'toy_type',
        '适用年龄段' => 'applicable_age',
        '3C认证证书编号' => 'certificate_no',
    ];


    /**
     * 返回对应的key
     * @param string $prosKey
     * @return string|false
     */
    public static function getMappingAutoInput(string $prosKey)
    {
        return self::$autoInput[$prosKey] ?? false;
    }

    /**
     * 销售属性匹配
     * @param array $skuVals
     * @param array $props
     */
    public static function getSaleSameSpec(array &$skuVals, array $props)
    {
        foreach ($skuVals as $k => $sku) {
            foreach ($props['values'] as $p => $val) {
                if (self::compareStrSimilar($sku['name'], $val['value'])) {
                    $skuVals[$k]['props'] = $val;
                    $skuVals[$k]['props']['parent_spec_id'] = $props['id'];
                    continue;
                }
            }
        }
    }

    /**
     * 删除本地下载后的图片
     * @param string $urlPath
     */
    public static function delLocalImg(string $urlPath)
    {
        $basePath = pathinfo($urlPath, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR;
        $fileName = pathinfo($urlPath, PATHINFO_FILENAME);
        $fileExt = pathinfo($urlPath, PATHINFO_EXTENSION);
        $orName = str_replace(['thumb_', 'cut_', 'img_water_', 'img_txt_', 'rotate_'], '', $fileName) . '.' . $fileExt;
        @unlink($basePath . 'thumb_' . $orName);
        @unlink($basePath . 'cut_' . $orName);
        @unlink($basePath . 'img_water_' . $orName);
        @unlink($basePath . 'img_txt_' . $orName);
        @unlink($basePath . 'rotate_' . $orName);
        @unlink($basePath . $orName);
    }


    /**
     * 商家编码设置
     * @param string $goodsNo
     * @param string $sourceId
     * @param string $platform
     * @param array $filter
     * @return string
     */
    public static function outGoodsId(string $goodsNo, array $filter, $sourceId, string $platform)
    {
        $outGoodsId = '';
        if (isset($filter['product_code_other_setting'])) {
            switch ($filter['product_code_other_setting']) {
                case 1://来源货号有则用，否则：留空
                    if (!empty($goodsNo)) $outGoodsId = $goodsNo;
                    break;
                case 2: //来源货号有则用，否则用：{来源ID}
                    if (!empty($goodsNo)) $outGoodsId = $sourceId;
                    break;
                case 3:
                    if (!empty($goodsNo)) $outGoodsId = $platform . '#' . $sourceId;
                    break;
                case 4:
                    $outGoodsId = $sourceId;
                    break;
                case 5:
                    $outGoodsId = $platform . '#' . $sourceId;
                    break;
                case 6:
                    $outGoodsId = StringHelper::getRandomStr(5) . $sourceId;
                    break;
            }
        }
        //前缀
        if (isset($filter['product_code_pre']) && !empty($filter['product_code_pre'])) {
            $outGoodsId = $filter['product_code_pre'] . $outGoodsId;
        }
        //后缀
        if (isset($filter['product_code_after']) && !empty($filter['product_code_after'])) {
            $outGoodsId = $outGoodsId . $filter['product_code_after'];
        }
        return $outGoodsId;

    }

    /**
     * 图片处理
     * @param string $imgUrl
     * @param array $settings
     * @return array|bool
     * @throws CopyException
     * @since 增加图片缩略宽度设置，设置宽度
     * @since 增加图片的宽高和大小返回
     */
    public static function processImage(string $imgUrl, array $settings = [])
    {
        try {
            $resultDownloadImg = ImagesHelper::downloadByUrl($imgUrl);
            if (!$resultDownloadImg) return false;
            list($path, $name) = $resultDownloadImg;
            $basePath = pathinfo($path, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR;
            /**
             * 文件不存在，跳过处理
             */
            if (!file_exists($path)) {
                return false;
            }
            list($width, $height) = @getimagesize($path);
            $size = filesize($path);


            /**
             * 图片超过1200宽度，则按照宽度800 进行压缩处理
             */
            if ($width > 1200) {
                $settings['is_compress'] = true;
                $settings['compress_width'] = 800;

            }
            /**
             * 图片容量超过1M 自动给压缩了，减少对内存的消耗
             */
            $sizeM = ($size / 1024 / 1024);
            if ($sizeM > 2 && !isset($settings['compress_percent'])) {
                return false;
            } elseif ($sizeM > 1 && $sizeM < 2) {
                /**
                 * 图片在1M 和2M之间的 压缩图片到原来的60
                 */
                $settings['is_compress'] = true;
                $settings['compress_percent'] = 60;
            }

            //压缩
            if (isset($settings['is_compress']) && !empty($settings['is_compress'])) {

                $quality = isset($settings['compress_percent']) && !empty($settings['compress_percent'])
                    ? intval($settings['compress_percent']) : 100;

                /**
                 * 如果设置了缩放宽度，则程序自动计算缩放高度,设置的缩放宽度需小于当前的
                 */
                if (isset($settings['compress_width']) && $settings['compress_width'] > 0
                    && $settings['compress_width'] < $width) {
                    $height = (intval($settings['compress_width']) * $height) / $width;
                    $width = $settings['compress_width'];
                }
                $path = ImagesHelper::thumbImg($path, $name, (int)$width, (int)$height, $quality);

                $size = filesize($path);
            }
            //水印
            if (isset($settings['is_water']) && !empty($settings['is_water'])) {
                //图片水印
                if (isset($settings['water_path']) && file_exists($settings['water_path']) && file_exists($path)) {
                    $resultPath = ImagesHelper::watermarkImg($path, $name, $settings['water_path'], intval($settings['water_position']));
                    if ($resultPath) {
                        $path = $resultPath;
                        $size = filesize($path);
                    }
                } elseif (isset($settings['water_txt']) && !empty($settings['water_txt']) && file_exists($path)) //文字水印
                {
                    if (isset($settings['font_type']) && !empty($settings['font_type'])) {
                        $fontFile = $settings['font_type'];
                    } else {
                        $fontFile = Yii::getAlias('@common/statics/font/Baoli.ttc');
                    }
                    $fontOption = is_array($settings['txt_option']) ? $settings['txt_option'] : [];
                    $resultPath = ImagesHelper::watermarkText($path, $name, $settings['water_txt'], $fontFile, $fontOption, intval($settings['water_position']));
                    if ($resultPath) {
                        $path = $resultPath;
                        $size = filesize($path);
                    }
                }
            }
            //旋转
            if (isset($settings['is_rotate']) && !empty($settings['is_rotate'])) {
                $rotateNum = isset($settings['rotate_num']) ? intval($settings['rotate_num']) : -8;

                Image::frame($path, 5, '666', 0)
                    ->rotate($rotateNum)
                    ->save($basePath . 'rotate_' . $name);
                $path = $basePath . 'rotate_' . $name;
                $size = filesize($path);
            }
            //裁剪
            if (isset($settings['is_cut']) && !empty($settings['is_cut'])) {
                $optionX = $optionY = 0;
                $cutWidth = $cutHeight = min($width, $height);
                if (isset($settings['cut_size']) && is_array($settings['cut_size'])) {
                    list($cutWidth, $cutHeight) = $settings['cut_size'];
                }
                if (isset($settings['cut_option']) && is_array($settings['cut_option'])) {
                    list($optionX, $optionY) = $settings['cut_option'];
                }

                //裁剪的尺寸和原图尺寸不相等才需要裁剪
                if ($cutHeight != $height || $cutWidth != $width) {
                    $width = $cutWidth;
                    $height = $cutHeight;
                    Image::crop($path, $cutWidth, $cutHeight, [$optionX, $optionY])
                        ->save($basePath . 'cut_' . $name);
                    $path = $basePath . 'cut_' . $name;
                    $size = filesize($path);
                }
            }
            return [$path, $width, $height, $size];
        } catch (Exception $e) {
            return false;
        } catch (RuntimeException $e) {
            return false;
        }

    }


    /**
     * 标题设置
     * @param string $title
     * @param array $setting
     * @param string $brand
     * @since 修复原始标题过长问题
     * @return false|string|string[]
     */
    public static function setTitle(string $title, array $setting, string $brand = '')
    {

//        print_r($setting);
        $oldTitle = $title;
        //前缀
        if (isset($setting['product_title_pre_content']) && !empty($setting['product_title_pre_content'])) {
            $title = $setting['product_title_pre_content'] . $title;
        }
        //后缀
        if (isset($setting['product_title_after_content']) && !empty($setting['product_title_after_content'])) {
            $title = $title . $setting['product_title_after_content'];
        }

        //关键词替换
        if (isset($setting['product_title_keywords_replace']) && is_array($setting['product_title_keywords_replace'])
            && count($setting['product_title_keywords_replace'])) {
            $searchWords = $replaceWords = [];
            foreach ($setting['product_title_keywords_replace'] as $keyword) {
                if (isset($keyword['keywords']) && isset($keyword['replace'])
                    && !empty($keyword['keywords']) && !empty($keyword['replace'])) {
                    array_push($searchWords, $keyword['keywords']);
                    array_push($replaceWords, $keyword['replace']);
                }
            }
            if (count($searchWords)) {
                $title = str_replace($searchWords, $replaceWords, $title);
            }
        }

        //过滤设置
        if (isset($setting['product_title_skip_setting']) && is_array($setting['product_title_skip_setting']) && count($setting['product_title_skip_setting'])) {
            //过滤货号,(剔除字符串中的非a~z 0-9 以外的所有特殊字符）
            if (in_array(1, $setting['product_title_skip_setting'])) {
                $title = preg_replace('/[a-z0-9|_|\-]/i', '', $title);
            }

            /**
             * 过滤品牌，业务逻辑调整为 适配商品属性中的品牌信息，如果品牌信息中含有品牌则过滤生效
             */
            if (in_array(2, $setting['product_title_skip_setting'])) {

                $title = str_replace($brand, '', $title);
            }

            //过滤括号及内容
            if (in_array(3, $setting['product_title_skip_setting'])) {
                $title = preg_replace('/\(.*?\)/', '', $title);
            }
        }
        //关键词删除
        if (isset($setting['product_title_del_keywords']) && !empty($setting['product_title_del_keywords'])) {
            $delKeywords = explode(',', $setting['product_title_del_keywords']);
            if (count($delKeywords)) {
                $title = str_replace($delKeywords, '', $title);
            }
        }
        $setting['product_title_cut_from'] == 1 ? $cutTitle = $title : $cutTitle = $oldTitle;
        //标题超过是否优化
        if (isset($setting['product_title_is_cut']) && StringHelper::calLenByGBK($cutTitle) > 60) {
            $cutTitle = $setting['product_title_cut_area'] == 1 ? StringHelper::strCutByGBK($cutTitle, 60, 2) : StringHelper::strCutByGBK($cutTitle, 60);

        }
        return $cutTitle;
    }


    /**
     * 非销售属性下级属性匹配，下级属性如果为必填项，则随机选择一项，如果为非必填项 则忽略
     * @param array $specData
     * @param array $property
     * @param array $sourceAttr
     * @param array $defaultAttr 默认配置
     * @return array
     */
    public static function notSaleSpecChildFilter(array $specData, array $property, array $sourceAttr, array $defaultAttr)
    {
        $sourceAttr = [];
        $newProperty = $property;

        //下级子属性匹配
        foreach ($property as $k => $item) {
            if ($item['template_pid'] > 0) {
                $item['vid'] = $item['vid'] == null ? 0 : intval($item['vid']);
                $childProps = self::getPropByParentId($specData, $item['template_pid'], $item['vid'], $sourceAttr, $defaultAttr);
                if (count($childProps)) {
                    $newProperty = array_merge($newProperty, $childProps);
                }
            }
        }
        return $newProperty;
    }


    private static function checkIsset(array $properts, array $item, int $id, string $nameAlias)
    {
        $checkProp = [];
        foreach ($properts as $p => $prop) {
            if ($prop['id'] == $id && $prop['vid'] == $item['vid']) {
                $checkProp[$item['vid']] = [
                    'ref_pid' => $id,
                    'value' => $item['value'],
                    'out_property_name' => $nameAlias,
                    'vid' => $item['vid'],
                    'template_pid' => $id,
                    'value_unit' => '',
                ];
                break 1;
            }
        }

        return $checkProp;
    }


    /**
     * 递归匹配所有非销售属性
     */
    public static function getPresRecursion(array $parentSpecList, array $sourceAttr, array &$checkProp = [])
    {


    }


    /**
     * 递归匹配下级子属性
     * @param array $specData
     * @param int $id
     * @param int $vid
     * @param array $sourceAttr 货源数据属性
     * @param array $checkProp
     * @param array $defaultAttr 默认配置
     * @return array
     */
    private static function getPropByParentId(array $specData, int $id, int $vid, array $sourceAttr, array $defaultAttr, array &$checkProp = [])
    {
        foreach ($specData as $k => $item) {
            if (!isset($item['parent_id']) || $item['parent_id'] != $id) {
                continue;
            }
            //必填属性才需要适配一条
            if ($item['required'] != true) {
                continue;
            }
            $properties = [];
            /**
             * 从商家再次匹配下，看是否能够匹配上
             */
            foreach ($sourceAttr as $s => $a) {
                if (PddSpec::compareStrSimilar($a['key'], (string)$item['name_alias'])) {
                    $properties = PddSpec::getNotSaleSpec($a, $item);
                    break;
                }
            }
            //选择类型的下级属性
            if (isset($item['values']) && is_array($item['values'])) {
                $checkedVal = '';
                if (empty($properties)) {
                    $checkKey = self::getMappingAutoInput($item['name_alias']);
                    if ($checkKey && isset($defaultAttr[$checkKey]) && !empty($defaultAttr[$checkKey])) {
                        $checkedVal = trim($defaultAttr[$checkKey]);
                    }
                }
                $mapValues = ArrayHelper::map($item['values'], 'value', 'vid');
                foreach ($item['values'] as $_k => $_item) {
                    if (!isset($_item['parent_vids']) || !is_array($_item['parent_vids'])) {
                        continue;
                    }
                    if (in_array($vid, $_item['parent_vids'])) {
                        if (!empty($checkedVal) && isset($mapValues[$checkedVal])) {
                            $checkVid = $mapValues[$checkedVal];
                            $checkProp[$checkVid] = [
                                'parent_spec_id' => $id,
                                'ref_pid' => $item['ref_pid'],
                                'template_pid' => $item['id'],
                                'value' => $checkedVal,
                                'out_property_name' => $item['name_alias'],
                                'vid' => $checkVid,
                                'value_unit' => '',
                            ];
                        } else {
                            $checkProp[$_item['vid']] = [
                                'parent_spec_id' => $id,
                                'ref_pid' => $item['ref_pid'],
                                'template_pid' => $item['id'],
                                'value' => $_item['value'],
                                'out_property_name' => $item['name_alias'],
                                'vid' => $_item['vid'],
                                'value_unit' => '',
                            ];
                        }
                        //如果是父属性，再次找下下级
                        if ($_item['is_parent'] == true) {
                            self::getPropByParentId($specData, $item['id'], $_item['vid'], $sourceAttr, $defaultAttr, $checkProp);
                        }
                        break 1;
                    }
                }
            } else {
                /**
                 * 手动填写的属性不存在下级属性，不需要再次递归获取
                 */
                if (empty($properties)) {
                    $checkKey = self::getMappingAutoInput($item['name_alias']);
                    if ($checkKey && isset($defaultAttr[$checkKey]) && !empty($defaultAttr[$checkKey])) {
                        $result['ref_pid'] = $item['ref_pid'];
                        //属性值类型（0-文本、1-数值、4-绝对时间、5-相对时间）
                        switch (@$item['value_type']) {
                            case 1: //数值
                                $result['value'] = intval($defaultAttr[$checkKey]);
                                break;
                            case 0:
                                $result['value'] = trim($defaultAttr[$checkKey]);
                                break;
                        }
                        $result['vid'] = null;
                        $result['template_pid'] = $item['id']; //增加属性id返回
                        $result['out_property_name'] = $item['name_alias'];
                        $result['value_unit'] = CopyHelper::getUnit($item['value_unit'] ?? '', $defaultAttr[$checkKey]);

                        $checkProp[$item['id']] = $result;
                    }
                } else {
                    $checkProp[$properties['template_pid']] = $properties;
                }
            }
        }
        return $checkProp;
    }


    /**
     * 品牌单独适配
     * @param array $prop
     * @param string $brandVal
     * @param PddFilterTpl $filter
     * @return array
     */
    public static function mappingBrand(array $prop, string $brandVal, PddFilterTpl $filter)
    {
        $brand = [];
        $brandVal = str_replace(' ', '', $brandVal);
        foreach ($prop['values'] as $k => $item) {
            switch ($filter->settings['basic']['product_brand']) {
                case 1: //软件自动对应,品牌字段需要全等匹配
                    if (trim($item['value']) == trim($brandVal)) {
                        $brand['vid'] = $item['vid'];
                        $brand['ref_pid'] = $prop['ref_pid'] ?? '';
                        $brand['template_pid'] = $prop['id'] ?? '';
                        $brand['value'] = $item['value'];
                        $brand['out_property_name'] = $prop['name_alias'];
                        $brand['value_unit'] = $prop['value_unit'];
                    }
                    break;
                case 2: //清空品牌，不填写
                    break;
                case 3: //手动输入品牌,品牌字段需要全等匹配
                    if (isset($filter->settings['basic']['product_brand_default'])) {
                        if (trim($item['value']) == trim($filter->settings['basic']['product_brand_default'])) {
                            $brand['vid'] = $item['vid'];
                            $brand['value'] = $item['value'];
                            $brand['out_property_name'] = $prop['name_alias'];
                            $brand['ref_pid'] = $prop['ref_pid'] ?? '';
                            $brand['template_pid'] = $prop['id'] ?? '';
                            $brand['value_unit'] = $prop['value_unit'];
                        }
                    }
                    break;
            }
        }
        //属性是否强制为空
        $brandCheckedEmpty = @$filter->settings['default_value']['brand_checked'];
        if (!$brandCheckedEmpty) {
            return $brand;
        } else {
            return [];
        }

    }


    /**
     * 智能适配非销售属性的key 和value
     * @param array $prop
     * @param array $sourceAttr
     * @param array $defaultArr
     * @param PddFilterTpl $filter
     * @return array
     * @since 品牌匹配改为全等操作
     */
    public static function notSalesProp(array $prop, array $sourceAttr, array $defaultArr, PddFilterTpl $filter)
    {
        $properties = [];
        foreach ($sourceAttr as $a => $attr) {
            if (PddSpec::compareStrSimilar($attr['key'], (string)$prop['name_alias'], 4)) //属性名匹配上
            {

                //针对品牌做特殊处理
                if ($attr['key'] == '品牌') {
                    if(is_array($attr['value'])){
                        $attr['value'] = $attr['value'][0];
                    }
                    $brand = self::mappingBrand($prop, $attr['value'], $filter);
                    if (!count($brand)) ;
                    {
                        return $brand;
                    }
                } else {
                    $properties = PddSpec::getNotSaleSpec($attr, $prop, $defaultArr);

                    if (empty($properties)) {
                        continue;
                    } else {
                        return $properties;
                    }
                }
                continue;
            }
        }

        return $properties;
    }


    /**
     * 非销售属性匹配
     * @param array $attr
     * @param array $props
     * @param array $defaultArr
     * @return array
     * @since 增加属性id返回 by wudg
     * @since 属性手动填写时单位适配bug修复，by wudg 2021-01-26
     */
    public static function getNotSaleSpec(array $attr, array $props, array $defaultArr = [])
    {

        //针对年龄属性 做特殊处理，需要对相似度做更高的设置
        $similar = 3;
        if ($attr['key'] == '适用年龄') {
            $similar = 5;
        }
        $result = [];
        //手填属性
        if (isset($props['values']) && is_array($props['values'])) {
            foreach ($props['values'] as $k => $prop) {
                /**
                 * 相似值替换
                 */
                if(is_array($attr['value'])){
                    $attr['value'] = $attr['value'][0];
                }
                $attr['value'] = self::transAttrSimilar($attr['value']);
                if (self::compareStrSimilar($attr['value'], $prop['value'], $similar)) {
                    $result['ref_pid'] = $props['ref_pid'];
                    $result['value'] = $prop['value'];
                    $result['template_pid'] = $props['id']; //增加属性id返回
                    $result['out_property_name'] = $props['name_alias'];
                    $result['vid'] = $prop['vid'];
                    $result['value_unit'] = CopyHelper::getUnit($prop['value_unit'] ?? '', $prop['value']);
                    break;
                }
                /**
                 * 再检查下是否设置了预设属性，有预设属性的 则再次适配下
                 */
                $checkKey = self::getMappingAutoInput($props['name_alias']);
                $checkVal = isset($defaultArr[$checkKey]) ? trim($defaultArr[$checkKey]) : null;
                if ($checkVal && $checkVal == $prop['value']) {
                    $result['ref_pid'] = $props['ref_pid'];
                    $result['value'] = $defaultArr[$checkKey];
                    $result['template_pid'] = $props['id']; //增加属性id返回
                    $result['out_property_name'] = $props['name_alias'];
                    $result['vid'] = $prop['vid'];
                    $result['value_unit'] = CopyHelper::getUnit($prop['value_unit'] ?? '', $prop['value']);
                    break;
                }
            }
        } else {
            //不存在values节点，则为手填写属性
            $result['ref_pid'] = $props['ref_pid'];
            //属性值类型（0-文本、1-数值、4-绝对时间、5-相对时间）
            switch (@$props['value_type']) {
                case 1: //数值
                    if(isset($props['min_value'])&&$props['min_value']){
                       if(intval($attr['value'])<$props['min_value']){
                           $attr['value'] = $props['min_value'];
                       }
                    }
                    $result['value'] = intval($attr['value']);
                    break;
                case 0:
                    $result['value'] = trim($attr['value']);
                    break;
                case 5: //生产日期
                    //生产日期 如果有设置默认，则使用默认的值
                    $checkedVal = strtotime($attr['value']);

                    if ($checkedVal == 0 || $checkedVal > time()) {
                        $checkKey = self::getMappingAutoInput($props['name_alias']);

                        if ($checkKey && isset($defaultArr[$checkKey]) && !empty($defaultArr[$checkKey])) {
                            $timeV = strtotime(trim($defaultArr[$checkKey]));
                            if ($timeV != 0 && $timeV < time()) {
                                $checkedVal = $timeV;
                            }
                        }
                    }
                    $result['value'] = date('Y-m-d', $checkedVal);
                    break;
            }

            //12-输入数值乘积-2维、13-输入数值乘积-3维
            /**
             * 对输入值再次处理下，如果碰到乘积关系的则需要重新处理
             */
            switch (@$props['control_type']) {
                case 12:
                    $result['value'] = $result['value'] . ',' . $result['value'];
                    break;
                case 13:
                    $result['value'] = $result['value'] . ',' . $result['value'] . ',' . $result['value'];
                    break;
            }
            $result['vid'] = null;
            $result['template_pid'] = $props['id']; //增加属性id返回
            $result['out_property_name'] = $props['name_alias'];
            $result['value_unit'] = CopyHelper::getUnit($props['value_unit'] ?? '', $attr['value']);
        }
        return $result;
    }


    /**
     * sku值设置
     * @param array $skuList
     * @param array $filter
     * @return array
     */
    public static function skuValueSettings(array $skuList, array $filter)
    {
        $delKeywords = $filter['product_sku_del_keywords'] ?? '';

        $delLKeywordsArr = explode(',', $delKeywords);

        $replaceWordsArr = $filter['product_sku_keywords_replace'] ?? [];
        $searchWords = $replaceWords = [];
        if (count($replaceWordsArr)) {
            $searchWords = ArrayHelper::getColumn($replaceWordsArr, 'keywords');
            $replaceWords = ArrayHelper::getColumn($replaceWordsArr, 'replace');
        }
        foreach ($skuList as $k => $sku) {
            $properties_name = $sku['properties_name'] ? json_decode($sku['properties_name'], true) : [];

            $tmp = [];
            foreach ($properties_name as $properties) {
//                list($key,$val) = explode(':',$properties);

                $listKeyList = explode(':', $properties);
                $key = $listKeyList[0] ?? '';
                unset($listKeyList[0]);
                $val = implode(':', $listKeyList);
                //关键词替换为空,删除关键词
                if (count($delLKeywordsArr)) {
                    $val = str_replace($delLKeywordsArr, '', $val);
                }

                //关键词替换
                if (count($searchWords) && count($replaceWords)) {
                    $val = str_replace($searchWords, $replaceWords, $val);
                }
                array_push($tmp, $key . ':' . $val);
            }
            $skuList[$k]['properties_name'] = StringHelper::jsonEncode($tmp);

        }
        return $skuList;
    }

    /**
     * 处理sku带图片的特殊信息
     * @param array $skuImg
     * @return array
     */
    public static function tripSkuImg(array $skuImg)
    {
        foreach ($skuImg as $k => $img) {
            //规格值剔除特殊符号
            $img['value'] = PddSpec::skuValueStrip($img['value']);
            //规格名称相似值替换
            $img['name'] = PddSpec::transSpecSimilar($img['name']);
            $skuImg[$k] = $img;
        }
        return $skuImg;
    }

    /**
     * 处理sku带图片的特殊信息
     * @param array $skuImg
     * @return array
     */
    public static function getMaxSmallTwo(array $properties_name)
    {
        $arr = array();
        $minlen = 0;
        $maxlen = 0;
        foreach ($properties_name as $k => $v) {
            if ($minlen == 0 || mb_strlen($v) < $minlen) {
                $minlen = mb_strlen($v);
                $arr['min'] = array(
                    'key' =>$k,
                    'word'=>$v,
                    'len'=>$minlen
                );
            }
            if ($maxlen == 0 || mb_strlen($v) > $maxlen) {
                $maxlen = mb_strlen($v);
                $arr['max'] = array(
                    'key' =>$k,
                    'word'=>$v,
                    'len'=>$maxlen
                );
            }

        }
        return $arr;
    }


    /**
     * skuList sku列表过滤
     * @param array $skuList
     * @return array
     */
    public static function tripSkuList(array $skuList)
    {
        foreach ($skuList as $k => $sku) {
            $properties_name = $sku['properties_name'] ? json_decode($sku['properties_name'], true) : [];

            $tmp = [];
            foreach ($properties_name as $properties) {
//                list($key,$val) = explode(':',$properties);
                $listKeyList = explode(':', $properties);
                $key = $listKeyList[0] ?? '';
                unset($listKeyList[0]);
                $val = implode(':', $listKeyList);
                //规格名称相似值替换
                $key = PddSpec::transSpecSimilar($key);
                //规格值剔除特殊符号
                $val = PddSpec::skuValueStrip($val);
                array_push($tmp, $key . ':' . $val);
            }
            $skuList[$k]['properties_name'] = StringHelper::jsonEncode($tmp);

        }
        return $skuList;
    }


    /**
     * 返回一级属性和下级属性列表
     * @param array $properties
     * @return array
     */
    public static function getPropsParentAndChild(array $properties)
    {

        $parentList = $childList = [];
        foreach ($properties as $k => $item) {
            if (isset($item['parent_id']) && $item['parent_id'] > 0) {
                array_push($childList, $item);
            } else {
                array_push($parentList, $item);
            }
        }
        return [$parentList, $childList];
    }


    /**
     * 处理来源数据的sku信息
     * @param array $skuList
     * @param array $skuImg
     * @since 规格名称做相似值替换，规格值剔除特殊特殊符号
     * @return array
     */
    public static function getSkuBySkuList(array $skuList, array $skuImg)
    {
        $transSkuImg = $formatSku = $skuData = [];
        foreach ($skuImg as $k => $img) {
            $transSkuImg[$img['name'] . ':' . $img['value']] = $img['skuImg'];
        }
        foreach ($skuList as $k => $sku) {
            $properties_name = $sku['properties_name'] ? json_decode($sku['properties_name'], true) : [];

            foreach ($properties_name as $properties) {

                $listKeyList = explode(':', $properties);
                $key = $listKeyList[0] ?? '';
                unset($listKeyList[0]);
                $val = implode(':', $listKeyList);
//                list($key,$val) = explode(':',$properties);
                $skuData[$key][] = $val;
            }
        }
        foreach ($skuData as $key => $skuVal) {
            $skuData[$key] = array_unique($skuVal);

            foreach ($skuData[$key] as $k => $val) {
                $skuData[$key][$k] = [
                    'name' => $val,
                    'img' => isset($transSkuImg[$key . ':' . $val]) ? $transSkuImg[$key . ':' . $val] : null,
                ];
            }
        }
        return $skuData;

    }


    /**
     * 比较两个字符串的相似性
     * @param string $compareStr
     * @param string $toCompareStr
     * @param int $similar
     * @return bool
     */
    public static function compareStrSimilar(string $compareStr, string $toCompareStr, int $similar = 2)
    {
        //是否全等
        if ($compareStr == $toCompareStr) {
            return true;
        }
        //是否包含
        if (strpos($compareStr, $toCompareStr) !== false || strpos($toCompareStr, $compareStr) !== false) {
            return true;
        }
        //有多少个字相同,默认2个字相同则表示匹配上
        $pattern = '/(?<!^)(?!$)/u';
        $compareArr = preg_split($pattern, $compareStr);
        $toCompareArr = preg_split($pattern, $toCompareStr);
        $intersect = array_intersect($compareArr, $toCompareArr);
        if (count($intersect) >= $similar) {
            return true;
        }

        return false;
    }


    /**
     * 翻译sku 映射的id信息
     * @param array $mappingData
     * @return array
     */
    public static function transSkuId(array $mappingData)
    {
        $transSkuId = [];
        foreach ($mappingData as $k => $skuName) {
            foreach ($skuName as $_k => $sku) {
                $transSkuId[$k . ':' . $sku['name']] = $sku['props']['spec_id'];
            }
        }
        return $transSkuId;
    }


    /**
     * 翻译sku 图片信息
     * @param array $mappingData
     * @return array
     */
    public static function transSkuImg(array $mappingData)
    {
        $transSkuImg = [];
        foreach ($mappingData as $k => $img) {
            $transSkuImg[$img['name'] . ':' . $img['value']] = $img['skuImg'];
        }
        return $transSkuImg;
    }


    /**
     * 市场价设置
     * @param $calPrice
     * @param array $priceSetting
     * @return float|int|mixed|string|string[]
     */
    public static function marketPrice($calPrice, array $priceSetting)
    {
        $market_price_percent = isset($priceSetting['market_price_percent_setting']) ? sprintf('%.2f', intval($priceSetting['market_price_percent_setting']) / 100) : 1;
        $market_price_add_setting = isset($priceSetting['market_price_add_setting']) ? intval($priceSetting['market_price_add_setting']) : 0;
        $marketPrice = sprintf('%.2f', $calPrice * $market_price_percent + $market_price_add_setting);

        //价格尾数替换,替换元
        if (isset($priceSetting['market_price_end_setting']) && $priceSetting['market_price_end_setting'] >= 0 && $priceSetting['market_price_end_setting'] < 10) {
            $marketPrice = substr_replace($marketPrice, $priceSetting['market_price_end_setting'], -4, 1);
        }
        $endDo = $priceSetting['market_price_end_do'] ?? 0;
        $marketPrice = self::endAmount($endDo, $marketPrice, $calPrice);
        $marketPrice = $marketPrice > $calPrice * 5 ? sprintf('%.2f', $calPrice * 5) : $marketPrice;
        return AmountHelper::yuanTofen($marketPrice);
    }


    /**
     * 最低sku价格计算
     * @param $calPrice
     * @param array $priceSetting
     * @return float|int
     */
    public static function lowestSkuPrice($calPrice, array $priceSetting)
    {
        $lowest_price_percent = isset($priceSetting['min_sku_price_percent_setting']) ? sprintf('%.2f', intval($priceSetting['min_sku_price_percent_setting']) / 100) : 1;
        $lowest_price_add_setting = isset($priceSetting['min_sku_price_add_setting']) ? intval($priceSetting['min_sku_price_add_setting']) : 0;
        $lowestPrice = sprintf('%.2f', $calPrice * $lowest_price_percent + $lowest_price_add_setting);

        //价格尾数替换,替换元
        if (isset($priceSetting['min_sku_price_end_setting']) && $priceSetting['min_sku_price_end_setting'] >= 0 && $priceSetting['min_sku_price_end_setting'] < 10) {
            $lowestPrice = substr_replace($lowestPrice, $priceSetting['min_sku_price_end_setting'], -4, 1);
        }
        $endDo = $priceSetting['min_sku_price_end_do'] ?? 0;
        $lowestPrice = self::endAmount($endDo, $lowestPrice, $calPrice);
        /**
         * 最低价sku 设置后超过了当前的计算值以计算值为准
         */
        $lowestPrice = $calPrice < $lowestPrice ? $calPrice : $lowestPrice;
        return AmountHelper::yuanTofen($lowestPrice);

    }


    /**
     * 团购价格设置
     * @param $calPrice
     * @param array $priceSetting
     * @return float|int|mixed|string|string[]
     */
    public static function multiPrice($calPrice, array $priceSetting)
    {

        $price_percent = isset($priceSetting['price_percent_setting']) ? sprintf('%.2f', intval($priceSetting['price_percent_setting']) / 100) : 1;
        $price_add_setting = isset($priceSetting['price_add_setting']) ? intval($priceSetting['price_add_setting']) : 0;

        $multiPrice = sprintf('%.2f', $calPrice * $price_percent + $price_add_setting);

        //价格尾数替换,替换元
        if (isset($priceSetting['price_end_setting']) && $priceSetting['price_end_setting'] >= 0 && $priceSetting['price_end_setting'] < 10) {
            $multiPrice = substr_replace($multiPrice, $priceSetting['price_end_setting'], -4, 1);
        }
        $endDo = $priceSetting['price_end_do'] ?? 0;
        $multiPrice = self::endAmount($endDo, $multiPrice, $calPrice);

        /**
         * 计算结果超过1.08倍 按照1.08倍计算
         */
        $multiPrice = $calPrice * 1.08 < $multiPrice ? sprintf('%.2f', $calPrice * 1.08) : $multiPrice;
        return AmountHelper::yuanTofen($multiPrice);
    }

    /**
     * 过滤销售属性值中的特殊符号
     * @param string $skuVal
     * @return string|string[]
     */
    public static function skuValueStrip(string $skuVal)
    {
        return str_replace(['【', '】', '，', '。', '&', '$', '*', '（', '）', ' '], '', $skuVal);
    }


    /**
     * 单买价设置
     * @param float $calPrice
     * @param array $priceSetting
     * @return float|int|mixed|string|string[]
     */
    public static function price($calPrice, array $priceSetting)
    {

        $single_price_percent = isset($priceSetting['single_price_percent_setting']) ? sprintf('%.2f', intval($priceSetting['price_percent_setting']) / 100) : 1;
        $single_price_add_setting = isset($priceSetting['single_price_add_setting']) ? intval($priceSetting['single_price_add_setting']) : 0;
        $singlePrice = sprintf('%.2f', $calPrice * $single_price_percent + $single_price_add_setting);

        //价格尾数替换,替换元
        if (isset($priceSetting['single_price_end_setting']) && $priceSetting['single_price_end_setting'] >= 0 && $priceSetting['single_price_end_setting'] < 10) {
            $singlePrice = substr_replace($singlePrice, $priceSetting['single_price_end_setting'], -4, 1);
        }
        $endDo = $priceSetting['single_price_end_do'] ?? 0;

        $singlePrice = self::endAmount($endDo, $singlePrice, $calPrice);
        //单买价格设置的值超过团购价*5，默认设置为团购价*5
        $singlePrice = $calPrice * 5 < $singlePrice ? $calPrice * 5 : $singlePrice;
        return AmountHelper::yuanTofen($singlePrice);
    }


    /**
     * 价格尾数处理
     * @param $endDo
     * @param $multiPrice
     * @param $calPrice
     * @return string|string[]
     */
    public static function endAmount($endDo, $multiPrice, $calPrice)
    {

        switch ($endDo) {
            case 1: //分角与来源保持一致
                $decimals = $calPrice - floor($calPrice);
                $multiPrice = intval($multiPrice) + $decimals;
                break;
            case 2: //保留分角，啥都不用做
                break;
            case 3: //去掉分角
                $multiPrice = intval($multiPrice);
                break;
            case 4: //去掉分

//                var_dump('去掉分:'.$multiPrice);
                $multiPrice = substr_replace($multiPrice, 0, -1, 1);
//                var_dump('去掉分hou :'.$multiPrice);
                break;
            default:
                break;
        }
        return $multiPrice;
    }


    /**
     * 属性相似值
     * @param string $spec
     * @return int|string
     */
    public static function transAttrSimilar(string $spec)
    {
        foreach (Yii::$app->params['similar_attr'] as $k => $specs) {
            if (in_array($spec, $specs)) {
                return $k;
            }
        }
        return $spec;
    }


    /**
     * SKU名称相似值
     * @param string $spec
     * @return string
     */
    public static function transSpecSimilar(string $spec)
    {

        foreach (Yii::$app->params['similar_props'] as $k => $specs) {
            if (in_array($spec, $specs)) {
                return $k;
            }
        }
        return $spec;
    }


    /**
     * 获取属性中的品牌信息
     * @param array $attr
     * @return string
     */
    public static function getBrandVal(array $attr)
    {
        foreach ($attr as $k => $item) {
            if ($item['key'] == '品牌') {
                return $item['value'];
            }
        }
        return '';
    }
}